import { UseOptions } from '../../interface/cmd'
import { DataType, Definitions, SwaggerDocSnd, UsePaths } from '../../interface/swagger'
import {
  TranslationPropType,
  getFileNameByTags,
  hasKey,
  isNormalType,
  removeDefine,
  removeDuplicate
} from '../../utils'
import {
  WorkeMod,
  apiName,
  getJsApiLine,
  getProperties,
  getTsApiLine,
  handleItems,
  handleNestVo,
  supplementArr,
  writeFile
} from './common'
import path from 'path'
import fs from 'fs'
export default function generateFileSnd(files: any, option: UseOptions, paths: UsePaths[]) {
  // 单文件生成
  const { fileLine, defineLine, useFileName } = generateSingleTagsSnd(
    files,
    paths,
    option.t,
    option.js
  )
  const _fileLine =
    `import ${apiName(
      useFileName
    )}  from './${useFileName}.d' \nimport request from './request'\n\n` + fileLine
  return writeFile(option.path, useFileName, _fileLine, defineLine, option.js)
}

/**
 * 生成单文件所需要的所有数据
 */
function generateSingleTagsSnd(
  file: SwaggerDocSnd,
  paths: UsePaths[],
  tagName: string,
  isJs: boolean = false
) {
  const tag = paths.filter((item) => item.tags === tagName)
  const useFileName = getFileNameByTags(tagName)
  let fileLine = ''
  if (isJs) {
    tag.forEach((item) => {
      fileLine += getJsApiLine(useFileName, item)
    })
  } else {
    tag.forEach((item) => {
      fileLine += getTsApiLine(useFileName, item)
    })
  }
  const defineLine = getSingleDefineLine(useFileName, tag, file)
  return {
    fileLine,
    defineLine,
    useFileName
  }
}

/**
 *
 * @param useFileName 生成文件名
 * @param paths 所有paths的集合
 * @param file 文件数据
 * @returns 返回生成.d.ts的所有行
 */
function getSingleDefineLine(useFileName: string, paths: UsePaths[], file: SwaggerDocSnd) {
  let defineTags = paths.map((item) => {
    return item.params && item.params!.indexOf('{') < 0 ? item.params : undefined
  })
  let responeTags = paths.map((item) => {
    return item.response && item.response!.indexOf('{') < 0
      ? item.response.replace(/\[\]/g, '')
      : undefined
  })
  responeTags = responeTags.filter(
    (item) =>
      item &&
      item !== DataType.Number &&
      item !== DataType.String &&
      item !== DataType.Boolen &&
      item !== 'number'
  )
  defineTags = [...defineTags, ...responeTags]
  const perfix = `export namespace ${apiName(useFileName)}{\n\tnamespace ${useFileName}{\n`
  let defineLine = ''
  // 去重
  defineTags = removeDuplicate(defineTags)
  defineTags = defineTags.filter((item) => item !== undefined)
  defineTags.forEach((defineName, index) => {
    if (defineName) {
      const define = getProperties(file.definitions, defineName)
      defineLine += define + '\n'
    }
  })
  // 补充数组嵌套数组指向Vo的类生成
  const supplementLine = handleNestVo(file.definitions)
  return perfix + defineLine + supplementLine + '\n}\n}'
}
